package com.weifly.weistock.record.option.impl;

import com.weifly.weistock.core.common.StockException;
import com.weifly.weistock.record.option.OptionConst;
import com.weifly.weistock.record.option.OptionParseService;
import com.weifly.weistock.record.option.domain.OptionRecordDto;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 原始交割单解析服务
 *
 * @author weifly
 * @since 2019/11/18
 */
public class OriginalFileParseService implements OptionParseService {

    private Logger log = LoggerFactory.getLogger(OriginalFileParseService.class);

    @Override
    public List<OptionRecordDto> parseRecord(File recordFile) throws IOException {
        FileInputStream fileInput = null;
        try{
            fileInput = new FileInputStream(recordFile);
            return this.parseRecord(fileInput);
        }finally {
            IOUtils.closeQuietly(fileInput);
        }
    }

    @Override
    public List<OptionRecordDto> parseRecord(InputStream input) throws IOException {
        List<OptionRecordDto> recordList = new ArrayList<>();
        try{
            BufferedReader reader = new BufferedReader(new InputStreamReader(input, "GBK"));
            String line = null;
            while((line=reader.readLine())!=null){
                if(StringUtils.isNotBlank(line)){
                    if(line.startsWith("----")){
                        continue;
                    }
                    if(line.startsWith("发生日期")){
                        continue;
                    }
                    OptionRecordDto recordDto = this.parseOne(line);
                    if(recordDto!=null){
                        recordList.add(recordDto);
                    }
                }
            }
        }finally {
            IOUtils.closeQuietly(input);
        }
        return recordList;
    }

    private OptionRecordDto parseOne(String line){
        String[] parts = line.split("\\s+");
        if(parts==null || parts.length<2){
            log.warn("非法行, line = " + line);
            return null;
        }

        // 合约编码应为数字，如果不是数字，就不处理
        try{
            Integer.parseInt(parts[2]);
        }catch(Exception e){
            log.info("合约编码不是数字，不处理此行：" + line);
            return null;
        }

        OptionRecordDto recordDto = new OptionRecordDto();
        recordDto.setDate(parts[0]);// 0 发生日期
        recordDto.setContractName(parts[1]); // 1 合约名称
        recordDto.setContractCode(parts[2]); // 2 合约编码
        recordDto.setStockCode(parts[3]); // 3 证券代码
        recordDto.setStockName(parts[4]); // 4 证券名称

        OptionConst.BusinessName businessName = OptionConst.BusinessName.getEnumByName(parts[5]); // 5 业务名称
        if(businessName==null){
            throw new StockException("业务名称不支持：" + parts[5]);
        }
        recordDto.setBusinessName(businessName);

        OptionConst.OperationType operationType = OptionConst.OperationType.getEnumByName(parts[6]); // 6 买卖标志
        if(operationType==null){
            throw new StockException("买卖标志不支持：" + parts[6]);
        }
        recordDto.setOperationType(operationType);

        OptionConst.HoldPosition holdPosition = OptionConst.HoldPosition.getEnumByName(parts[7]); // 7 持仓方向
        if(holdPosition==null){
            throw new StockException("持仓方向不支持：" + parts[7]);
        }
        recordDto.setHoldPosition(holdPosition);

        recordDto.setTradePrice(Double.valueOf(parts[8]));// 8 成交价格
        recordDto.setTradeNumber(Double.valueOf(parts[9]).intValue());// 9 成交数量
        recordDto.setTradeAmount(Double.valueOf(parts[10]));// 10 成交金额
        recordDto.setFeeService(Double.valueOf(parts[11]));// 11 手续费
        recordDto.setFeeStamp(Double.valueOf(parts[12]));// 12 印花税
        recordDto.setFeeTransfer(Double.valueOf(parts[13]));// 13 过户费
        recordDto.setFeeExtra(Double.valueOf(parts[14]));// 14 附加费
        recordDto.setFeeClear(Double.valueOf(parts[15]));// 15 交易所清算费
        recordDto.setClearAmount(Double.valueOf(parts[16]));// 16 清算金额
        recordDto.setAfterAmount(Double.valueOf(parts[17]));// 17 资金本次余额
        recordDto.setAfterNumber(Double.valueOf(parts[18]).intValue());// 18 剩余数量
        recordDto.setEntrustCode(parts[19]);// 19 委托编号
        recordDto.setTime(parts[20]); // 20 成交时间
        // 21 股东代码
        // 22 备注
        return recordDto;
    }
}
